diff -cr xblockbuster1.00/patchlevel.h xblockbuster1.01/patchlevel.h
*** xblockbuster1.00/patchlevel.h	Fri Mar 12 23:48:29 1993
--- xblockbuster1.01/patchlevel.h	Thu Mar 18 01:34:39 1993
***************
*** 1 ****
! #define VERSION	"XBlockBuster 1.00"
--- 1 ----
! #define VERSION	"XBlockBuster 1.01"
diff -cr xblockbuster1.00/CHANGES xblockbuster1.01/CHANGES
*** xblockbuster1.00/CHANGES	Wed Mar 10 17:57:12 1993
--- xblockbuster1.01/CHANGES	Sat Mar 20 03:26:53 1993
***************
*** 1,4 ****
! XBlockBuster v1.00:
  
   Converted to run under X11 instead of SunView.
  
--- 1,33 ----
! Changes from v1.00 to v1.01
! 
!   Fixed the Imakefile so StageDir now works properly.
! 
!   PATHLENGTH (in xblockbuster.h) increased from 64 to 512
! 
!   sprintf is no longer assumed to return its first arguement (ANSI C it
!   returns the number of characters transferred.)  Thanks David Sanderson
! 
!   SysV/Ultrix support added (put -DSYSV in the define line in the Makefile/
!   Imakefile). Thanks ykcheu@eos.ncsu.edu
! 
!   Added code so that XBlockBuster will hopefully work better on displays
!   in which BlackPixel == 0 (Xor didn't work at all on those systems.)
! 
!   Moved FONT from the (I)Makefile to xblockbuster.h.   The FONT, as
!   defined, should work fine.  Moved there because if a nice title screen
!   is ever added, a different font will be used there, and I don't really
!   want 2 or 3 font declarations on the compile line.
! 
!   Changed the XmbSetWMProperties to XSetWMProperties in xblockbuster.c.  From
!   the man page, it appears that the former is standard X11R5, but some
!   systems don't have it, and XSetWMProperties does the job fine.
! 
!   Added RAND and SRAND defines to xblockbuster.h.  Some machines don't
!   seem to have the random and srandom functions.  These macros should make
!   it easier for these people to fix that problem.
! 
! -----------------------------------------------------------------------------
! Changes from Sunview BlockBuster to XBlockBuster v1.00:
  
   Converted to run under X11 instead of SunView.
  
diff -cr xblockbuster1.00/Imakefile xblockbuster1.01/Imakefile
*** xblockbuster1.00/Imakefile	Sat Mar 13 02:20:09 1993
--- xblockbuster1.01/Imakefile	Mon Mar 22 20:18:02 1993
***************
*** 1,26 ****
  XCOMM $XConsortium: Imakefile,v 1.9 91/07/16 23:06:01 gildea Exp $
! /*	 BINDIR = /usr/games/
  */
! 	   FONT	= -DFONT=\"10x20\"
! /*	 MANDIR = /usr/local/man/man6
  */
        MANSUFFIX = 6
! /*
!        STAGEDIR = /usr/games/lib/xblockbuster
! */
! #ifndef STAGEDIR
! #define STAGEDIR = LIBDIR
  #endif
  
! 	DEFINES = $(FONT) -DSTAGEDIR=\"$(STAGEDIR)\"
          DEPLIBS = $(DEPXLIB)
  LOCAL_LIBRARIES = $(XLIB)
            SRCS1 = balls_pallet.c bricks.c deflection.c save.c score.c stage.c \
! 			xblockbuster.c
            OBJS1 = balls_pallet.o bricks.o deflection.o save.o score.o stage.o \
! 			xblockbuster.o
! 	  SRCS2 = stagemm.c
! 	  OBJS2 = stagemm.o
         PROGRAMS = xblockbuster stagemm
  
  ComplexProgramTarget_1(xblockbuster,$(LOCAL_LIBRARIES),-lm)
--- 1,30 ----
  XCOMM $XConsortium: Imakefile,v 1.9 91/07/16 23:06:01 gildea Exp $
! /*       BINDIR = /usr/games/
  */
! /*       MANDIR = /usr/local/man/man6
  */
        MANSUFFIX = 6
! 
! #define StageDir /usr/games/lib/xblockbuster
! 
! #define InstallLib YES	/* Change to NO if the stages are already installed */
! 
! #ifndef StageDir
! #define StageDir $(LIBDIR)/xblockbuster
  #endif
  
! STAGEDIR = StageDir
! /* If your on a system V machine, add -DSYSV to DEFINES below */
! 
!         DEFINES = -DSTAGEDIR=\"$(STAGEDIR)\"
          DEPLIBS = $(DEPXLIB)
  LOCAL_LIBRARIES = $(XLIB)
            SRCS1 = balls_pallet.c bricks.c deflection.c save.c score.c stage.c \
!                   xblockbuster.c
            OBJS1 = balls_pallet.o bricks.o deflection.o save.o score.o stage.o \
!                   xblockbuster.o
!           SRCS2 = stagemm.c
!           OBJS2 = stagemm.o
         PROGRAMS = xblockbuster stagemm
  
  ComplexProgramTarget_1(xblockbuster,$(LOCAL_LIBRARIES),-lm)
***************
*** 33,41 ****
    There must be a better way of doing this install, other than listing
    the 40 or so files and doing a InstallMultiple.
  */
  install::
  	MakeDir($(STAGEDIR))
  	cp -r STAGES* $(STAGEDIR)
  	chmod 666 $(STAGEDIR)/STAGES*/scores
  	chmod 777 $(STAGEDIR)/STAGES*/save
! 
--- 37,46 ----
    There must be a better way of doing this install, other than listing
    the 40 or so files and doing a InstallMultiple.
  */
+ #if InstallLib
  install::
  	MakeDir($(STAGEDIR))
  	cp -r STAGES* $(STAGEDIR)
  	chmod 666 $(STAGEDIR)/STAGES*/scores
  	chmod 777 $(STAGEDIR)/STAGES*/save
! #endif
Only in xblockbuster1.00: Makefile
diff -cr xblockbuster1.00/Makefile.noIm xblockbuster1.01/Makefile.noIm
*** xblockbuster1.00/Makefile.noIm	Fri Mar 19 01:19:41 1993
--- xblockbuster1.01/Makefile.noIm	Sat Mar 20 03:11:41 1993
***************
*** 15,26 ****
  MANDIR = /usr/local/man/man6/
  MANEXT = 6
  
- # Font to use for writing text.
- FONT = 10x20
  
  CC = cc
! # IF you want to change the FONT or LIBDIR, do it above
! CFLAGS= -O -DFONT=\"${FONT}\"  -DSTAGEDIR=\"${LIBDIR}\"
  LDFLAGS=
  LIBS= -lm -lX11
  
--- 15,27 ----
  MANDIR = /usr/local/man/man6/
  MANEXT = 6
  
  
+ # If you want change LIBDIR, do it above
+ # If on a System V machine, add -DSYSV to CFLAGS
+ DEFINES =  -DSTAGEDIR=\"${LIBDIR}\"
+ 
  CC = cc
! CFLAGS = -O $(DEFINES)
  LDFLAGS=
  LIBS= -lm -lX11
  
***************
*** 37,42 ****
--- 38,50 ----
  	cp -r STAGES* ${LIBDIR}
  	chmod 666 ${LIBDIR}/STAGES*/scores
  	chmod 777 ${LIBDIR}/STAGES*/save
+ 	cp XBlockbuster.ad ${LIBDIR}
+ 	cp xblockbuster ${BINDIR}/xblockbuster
+ 	cp xblockbuster.man ${MANDIR}/xblockbuster.${MANEXT}
+ 	cp stagemm ${BINDIR}/stagemm
+ 	cp stagemm.man ${MANDIR}/stagemm.${MANEXT}
+ 
+ install.bin:
  	cp XBlockbuster.ad ${LIBDIR}
  	cp xblockbuster ${BINDIR}/xblockbuster
  	cp xblockbuster.man ${MANDIR}/xblockbuster.${MANEXT}
diff -cr xblockbuster1.00/README xblockbuster1.01/README
*** xblockbuster1.00/README	Sat Mar 13 00:15:30 1993
--- xblockbuster1.01/README	Mon Mar 22 20:07:43 1993
***************
*** 12,43 ****
  
  TO BUILD:
  
!     If you want to use the Imakefile, all that is needed is:
  
  	1) xmkmf
  	2) make
  	3) make install
  
      If you don't want to use the Imakefile, do the following:
  	1) cp Makefile.noIm Makefile
  	2) Edit the Makefile.  Everything should be fairly well documented.
-            You should make sure that whatever FONT is defined to is available
- 	   on your system, or the program will not work (use xlsfonts to see
- 	   what fonts your server provides.)  I believe the default font as
- 	    distributed (10x20) is part of the X11R5 distribution.
  	3) make
  	4) make install
  
! 	XBlockbuster can use the same playground that Blockbuster (the sunview
! version) does, if you already have that installed.  Set LIBDIR appropriately
! to use the same playground.
  
! 	I have successfully compiled the source with both cc and gcc on
! a sun 3/sunos 4.1.1.
  
! 	After you have set up the Makefile to your satisfaction, type:
  
  
  FILES (of interest):
  
  CHANGES: changes made from blockbuster to xblockbuster.
--- 12,78 ----
  
  TO BUILD:
  
!     If you are on a System V machine, -DSYSV will need to be added to the
!     DEFINES variable.
  
+     XBlockbuster can use the same playground that Blockbuster (the sunview
+     version) does.  If you want to use the same playground, set 
+     StageDir (Imakefile) or LIBDIR (Makefile.noIm) appropriately.
+ 
+   IMAKEFILE directions:
+ 
+     If you have already installed the stages file for xblockbuster, and
+     don't want to copy over them, change InstallLib in Imakefile to No.
+ 
+     The Imakefile, as distributed, should work fine (unless on System V).  You
+     may still want to edit the Imakefile to change where the files will
+     be installed.  Once you have edited the Imakefile to your satisfaction,
+     all that is needed is:
+ 
  	1) xmkmf
  	2) make
  	3) make install
  
+   MAKEFILE directions:
+ 
      If you don't want to use the Imakefile, do the following:
  	1) cp Makefile.noIm Makefile
  	2) Edit the Makefile.  Everything should be fairly well documented.
  	3) make
+ 
+ 	If you have already installed the XBlockBuster stages, and don't
+ 	want to copy over them, do:
+ 
+ 	4) make install.bin
+ 
+ 	If this is your first installation, or you want to copy over the
+ 	score files, do:
+ 
  	4) make install
  
!     I have successfully compiled the source with both cc and gcc on
!     a sun 3/sunos 4.1.1.
  
! IF YOU HAVE PROBLEMS:
  
! 	If it can't find the font, change FONT in xblockbuster.h
  
+ 	If your on system V/Ultrix machine, did you add -DSYSV to to
+ 	defines?
  
+ 	If you get link errors of random or srandom not found, change RAND
+ 	and SRAND in xblockbuster.h to comparable functions for your
+ 	machine (and please send me mail, so I can make this more automatic
+ 	in the future.)  Note that RAND and SRAND are only used for
+ 	determining what the order of the stages are, so they need not
+ 	be especially good.
+ 
+ 	Check the BUGS/TODO section to see if it is a problem I
+ 	already know about.  If it is, still send me mail, but maybe
+ 	by it being a known problem, you won't feel quite so bad.
+ 
+ 	Other problems?  Send me mail. (see below)
+ 
  FILES (of interest):
  
  CHANGES: changes made from blockbuster to xblockbuster.
***************
*** 56,63 ****
  	(See the manual page for more information on coloring the bricks and
  	alternate bricks.)
  
! TODO:
  
   A nice opening screen, showing the bricks (with proper coloring, if 
  applicable), along with descriptions of what each brick does.
  
--- 91,106 ----
  	(See the manual page for more information on coloring the bricks and
  	alternate bricks.)
  
! BUGS/TODO:
  
+  I have gotten several reports of the pallette not appearing on the
+ screen, yet the balls are appearing (both use the gc_xor structure, so
+ I don't have any idea what the problem is, and can't reproduce it
+ myself.)  This problem seems to be happening more on BW systems.  My
+ only thought right now is perhaps the window wasn't made the proper size,
+ so the bottom is cut off.  But even then, if the pointer is moved near
+ the top of the window, the side crosshairs should still appear.
+ 
   A nice opening screen, showing the bricks (with proper coloring, if 
  applicable), along with descriptions of what each brick does.
  
***************
*** 79,85 ****
  
  	I will maintain it and release patches as required. 
  
  Mark Wedel
  master@cats.ucsc.edu
! March 10, 1993
  
--- 122,132 ----
  
  	I will maintain it and release patches as required. 
  
+ 	If you send me mail, please include a valid mail address as
+ part of your signature.  I have gotten at least a few letters where
+ the mail address in the header was incorrect.
+ 
  Mark Wedel
  master@cats.ucsc.edu
! March 17, 1993
  
Common subdirectories: xblockbuster1.00/SKELS and xblockbuster1.01/SKELS
Common subdirectories: xblockbuster1.00/STAGES and xblockbuster1.01/STAGES
Common subdirectories: xblockbuster1.00/STAGES.try and xblockbuster1.01/STAGES.try
Common subdirectories: xblockbuster1.00/STAGES.wacko and xblockbuster1.01/STAGES.wacko
diff -cr xblockbuster1.00/balls_pallet.c xblockbuster1.01/balls_pallet.c
*** xblockbuster1.00/balls_pallet.c	Mon Nov 16 23:29:32 1992
--- xblockbuster1.01/balls_pallet.c	Fri Mar 19 02:12:30 1993
***************
*** 47,86 ****
  	ball_pr = XCreateBitmapFromData(display, win, ball_bits, ball_width, ball_height);
  }
  
! /* Macro to draw a ball */
! 
! #define draw_ball( ball )      \
! 	XCopyPlane(display, ball_pr, win, gc_xor, 0, 0, 16, 16, \
  		(int)( (ball)->x ) - 8, (int)( (ball)->y ) - 8, 1)
  
- 
  /* Procedure to draw the pallet */
  void
! draw_pallet(  )
  {
! 	XDrawLine( display, win, gc_xor, pallet_xI - pallet_lengthI + 2, pallet_yI,
  		   pallet_xI + pallet_lengthI - 2, pallet_yI);
! 	XDrawLine( display, win, gc_xor, pallet_xI - pallet_lengthI + 1, pallet_yI + 1,
  		   pallet_xI + pallet_lengthI - 1, pallet_yI + 1);
! 	XDrawLine( display, win, gc_xor, pallet_xI - pallet_lengthI, pallet_yI + 2,
  		   pallet_xI + pallet_lengthI, pallet_yI + 2);
! 	XDrawLine( display, win, gc_xor, pallet_xI - 1, pallet_yI + 3,
  		   pallet_xI - 1, pallet_yI + 6);
! 	XDrawLine( display, win, gc_xor, pallet_xI - 1, pallet_yI + 6,
  		   pallet_xI + 1, pallet_yI + 6);
! 	XDrawLine( display, win, gc_xor, pallet_xI + 1, pallet_yI + 6,
  		   pallet_xI + 1, pallet_yI + 3);
! 	XDrawLine( display, win, gc_xor, 0, mouse_yI - 1,	/* <HC> */
  		   10, mouse_yI - 1);
! 	XDrawLine( display, win, gc_xor, 0, mouse_yI,
  		   10, mouse_yI);
! 	XDrawLine( display, win, gc_xor, 0, mouse_yI + 1,	/* <HC> */
  		   10, mouse_yI + 1);
! 	XDrawLine( display, win, gc_xor, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI - 1,	/* <HC> */
  		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI - 1);
! 	XDrawLine( display, win, gc_xor, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI,
  		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI);
! 	XDrawLine( display, win, gc_xor, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI + 1,	/* <HC> */
  		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI + 1);
  }
  
--- 47,84 ----
  	ball_pr = XCreateBitmapFromData(display, win, ball_bits, ball_width, ball_height);
  }
  
! #define draw_ball( ball, gc )      \
! 	XCopyPlane(display, ball_pr, win, gc, 0, 0, 16, 16, \
  		(int)( (ball)->x ) - 8, (int)( (ball)->y ) - 8, 1)
  
  /* Procedure to draw the pallet */
  void
! draw_pallet( gc )
! GC gc;
  {
! 	XDrawLine( display, win, gc, pallet_xI - pallet_lengthI + 2, pallet_yI,
  		   pallet_xI + pallet_lengthI - 2, pallet_yI);
! 	XDrawLine( display, win, gc, pallet_xI - pallet_lengthI + 1, pallet_yI + 1,
  		   pallet_xI + pallet_lengthI - 1, pallet_yI + 1);
! 	XDrawLine( display, win, gc, pallet_xI - pallet_lengthI, pallet_yI + 2,
  		   pallet_xI + pallet_lengthI, pallet_yI + 2);
! 	XDrawLine( display, win, gc, pallet_xI - 1, pallet_yI + 3,
  		   pallet_xI - 1, pallet_yI + 6);
! 	XDrawLine( display, win, gc, pallet_xI - 1, pallet_yI + 6,
  		   pallet_xI + 1, pallet_yI + 6);
! 	XDrawLine( display, win, gc, pallet_xI + 1, pallet_yI + 6,
  		   pallet_xI + 1, pallet_yI + 3);
! 	XDrawLine( display, win, gc, 0, mouse_yI - 1,	/* <HC> */
  		   10, mouse_yI - 1);
! 	XDrawLine( display, win, gc, 0, mouse_yI,
  		   10, mouse_yI);
! 	XDrawLine( display, win, gc, 0, mouse_yI + 1,	/* <HC> */
  		   10, mouse_yI + 1);
! 	XDrawLine( display, win, gc, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI - 1,	/* <HC> */
  		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI - 1);
! 	XDrawLine( display, win, gc, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI,
  		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI);
! 	XDrawLine( display, win, gc, STAGE_WIDTH_IN_PIXELS - 1, mouse_yI + 1,	/* <HC> */
  		   STAGE_WIDTH_IN_PIXELS - 11, mouse_yI + 1);
  }
  
***************
*** 145,151 ****
  						  /* NW */ : -M_SQRT2_2 );
  		ball->y_speed = launch_speed * -M_SQRT2_2;
  		/* initial ball image */
! 		draw_ball( ball );
  		/* show balls left */
  		print_balls();
  		/* show speeds */
--- 143,149 ----
  						  /* NW */ : -M_SQRT2_2 );
  		ball->y_speed = launch_speed * -M_SQRT2_2;
  		/* initial ball image */
! 		draw_ball( ball, gc_xor );
  		/* show balls left */
  		print_balls();
  		/* show speeds */
***************
*** 240,252 ****
  		break;
  	case 'C':		/* clipper */
  		if ( ++( brick->nhits ) == 2 ) {
! 			draw_pallet();
  			pallet_lengthI -= pallet_lengthI / 5;
  			if ( pallet_lengthI < MIN_PALLET_LENGTH )
  				pallet_lengthI = MIN_PALLET_LENGTH;
  			pallet_length = ( double ) pallet_lengthI;
  			busted = TRUE;
! 			draw_pallet();
  		}
  		break;
  	case 'D':		/* double */
--- 238,250 ----
  		break;
  	case 'C':		/* clipper */
  		if ( ++( brick->nhits ) == 2 ) {
! 			draw_pallet(gc_xor);
  			pallet_lengthI -= pallet_lengthI / 5;
  			if ( pallet_lengthI < MIN_PALLET_LENGTH )
  				pallet_lengthI = MIN_PALLET_LENGTH;
  			pallet_length = ( double ) pallet_lengthI;
  			busted = TRUE;
! 			draw_pallet(gc_xor);
  		}
  		break;
  	case 'D':		/* double */
***************
*** 425,434 ****
  	/* redraw brick (never on the sides) */
  	if ( redraw ) {
  		if ( pallet_row == ball->row )
! 			draw_pallet(  );	/* avoid shadow */
  		draw_brick( ball->row, ball->col );
  		if ( pallet_row == ball->row )
! 			draw_pallet(  );	/* restore */
  	}
  	/* deflection */
  	if ( ball->col <= 0 || ball->col >= MAX_COL ) {
--- 423,432 ----
  	/* redraw brick (never on the sides) */
  	if ( redraw ) {
  		if ( pallet_row == ball->row )
! 			draw_pallet(gc_xor );	/* avoid shadow */
  		draw_brick( ball->row, ball->col );
  		if ( pallet_row == ball->row )
! 			draw_pallet(gc_xor  );	/* restore */
  	}
  	/* deflection */
  	if ( ball->col <= 0 || ball->col >= MAX_COL ) {
***************
*** 462,468 ****
  	register int    score_hit = FALSE;	/* boolean */
  
  	/* erase ball image */
! 	draw_ball( ball );
  
  	/* move ball */
  	ball->x += ball->x_speed;
--- 460,466 ----
  	register int    score_hit = FALSE;	/* boolean */
  
  	/* erase ball image */
! 	draw_ball( ball, gc_xor );
  
  	/* move ball */
  	ball->x += ball->x_speed;
***************
*** 494,500 ****
  		pallet_deflection( ball );
  	}
  	/* redraw ball image */
! 	draw_ball( ball );
  
  	return ( score_hit );
  }
--- 492,498 ----
  		pallet_deflection( ball );
  	}
  	/* redraw ball image */
! 	draw_ball( ball,gc_xor );
  
  	return ( score_hit );
  }
***************
*** 522,535 ****
  }
  
  
! void draw_balls()
  {
! 	if ( ball1.quadrant ) draw_ball(&ball1);
! 	if ( ball2.quadrant ) draw_ball(&ball2);
! 	if ( ball3.quadrant ) draw_ball(&ball3);
  }
  
- 
  /*** on timeout event ***/
  void move_balls( )
  {
--- 520,533 ----
  }
  
  
! void draw_all_balls()
  {
! 	if (ball1.quadrant) draw_ball(&ball1, gc_xor);
! 	if (ball2.quadrant) draw_ball(&ball2, gc_xor);
! 	if (ball3.quadrant) draw_ball(&ball3, gc_xor);
! 
  }
  
  /*** on timeout event ***/
  void move_balls( )
  {
***************
*** 564,580 ****
  		if ( ball1.quadrant ) {
  			ball1.quadrant = NO_BALL;
  			balls_left++;	/* kludge to avoid consuming the ball */
! 			draw_ball( &ball1 );
  		}
  		if ( ball2.quadrant ) {
  			ball2.quadrant = NO_BALL;
  			balls_left++;	/* kludge to avoid consuming the ball */
! 			draw_ball( &ball2 );
  		}
  		if ( ball3.quadrant ) {
  			ball3.quadrant = NO_BALL;
  			balls_left++;	/* kludge to avoid consuming the ball */
! 			draw_ball( &ball3 );
  		}
  		/* update score */
  		print_score();
--- 562,578 ----
  		if ( ball1.quadrant ) {
  			ball1.quadrant = NO_BALL;
  			balls_left++;	/* kludge to avoid consuming the ball */
! 			draw_ball( &ball1, gc_xor );
  		}
  		if ( ball2.quadrant ) {
  			ball2.quadrant = NO_BALL;
  			balls_left++;	/* kludge to avoid consuming the ball */
! 			draw_ball( &ball2, gc_xor );
  		}
  		if ( ball3.quadrant ) {
  			ball3.quadrant = NO_BALL;
  			balls_left++;	/* kludge to avoid consuming the ball */
! 			draw_ball( &ball3, gc_xor );
  		}
  		/* update score */
  		print_score();
Common subdirectories: xblockbuster1.00/icons and xblockbuster1.01/icons
diff -cr xblockbuster1.00/save.c xblockbuster1.01/save.c
*** xblockbuster1.00/save.c	Mon Nov 16 23:35:53 1992
--- xblockbuster1.01/save.c	Thu Mar 18 16:22:53 1993
***************
*** 16,22 ****
  	char            sve[SAVEFILE_LENGTH];
  	register int    stage_nb_tmp;
  
! 	if ((fd = fopen( sprintf( sve, SAVEFILE, playground, login ),"r+" ))) {
  		/* restoring save file */
  		XDrawImageString(display, win, gc, OFFSET_BALLS,
  			font_height, "Restoring...",12);
--- 16,23 ----
  	char            sve[SAVEFILE_LENGTH];
  	register int    stage_nb_tmp;
  
! 	sprintf(sve, SAVEFILE, playground, login );
! 	if ((fd = fopen(sve, "r+"))) {
  		/* restoring save file */
  		XDrawImageString(display, win, gc, OFFSET_BALLS,
  			font_height, "Restoring...",12);
***************
*** 53,60 ****
  	char            sve[SAVEFILE_LENGTH];
  	register int    stage_nb_tmp = 0;
  
! 	if ( !( fd = fopen( sprintf( sve, SAVEFILE, playground, login ),
! 			    "w" ) ) ) {
  		perror( "Can't open save file" );
  		exit( 1 );
  	}
--- 54,61 ----
  	char            sve[SAVEFILE_LENGTH];
  	register int    stage_nb_tmp = 0;
  
! 	sprintf( sve, SAVEFILE, playground, login );
! 	if ( !( fd = fopen(sve, "w" ))) {
  		perror( "Can't open save file" );
  		exit( 1 );
  	}
diff -cr xblockbuster1.00/score.c xblockbuster1.01/score.c
*** xblockbuster1.00/score.c	Mon Nov 16 23:32:19 1992
--- xblockbuster1.01/score.c	Thu Mar 18 16:49:56 1993
***************
*** 38,45 ****
  show_score_board(  )
  {
  	register int    lows, s, ns,scorenum=0;
! 	register int    update = FALSE;
! 	register int    made_it = FALSE;
  	FILE           *fd;
  	char            buf[PATH_LENGTH];
  
--- 38,44 ----
  show_score_board(  )
  {
  	register int    lows, s, ns,scorenum=0;
! 	int		update = FALSE,made_it = FALSE,width;
  	FILE           *fd;
  	char            buf[PATH_LENGTH];
  
***************
*** 53,59 ****
  	}
  
  	/* read the score file into the array */
! 	if ( !( fd = fopen( sprintf( buf, SCOREFILE, playground ), "r+" ) ) ) {
  		perror( "No score file" );
  		exit( 1 );
  	}
--- 52,59 ----
  	}
  
  	/* read the score file into the array */
! 	sprintf( buf, SCOREFILE, playground );
! 	if ( !( fd = fopen(buf, "r+" ) ) ) {
  		perror( "No score file" );
  		exit( 1 );
  	}
***************
*** 115,155 ****
  	/* show score board */
  	center_text( 0, "Top Scores" );
  	for ( s = 0; s < NB_SCORES; s++ ) {
! 		if ( score_board[s].balls_left > 99 ) {
! 			center_text( s + 2, sprintf( buf, "%7d (%3d)   %8s ",
! 					     score_board[s].score,
! 					     score_board[s].balls_left,
! 					     score_board[s].login ) );
! 		} else if ( score_board[s].balls_left > 9 ) {
! 			center_text( s + 2, sprintf( buf, "%7d  (%2d)   %8s ",
! 					     score_board[s].score,
! 					     score_board[s].balls_left,
! 					     score_board[s].login ) );
! 		} else if ( score_board[s].balls_left > 0 ) {
! 			center_text( s + 2, sprintf( buf, "%7d   (%1d)   %8s ",
! 					     score_board[s].score,
! 					     score_board[s].balls_left,
! 					     score_board[s].login ) );
! 		} else if ( score_board[s].balls_left < -99 ) {
! 			center_text( s + 2, sprintf( buf, "%7d (%3d) + %8s ",
! 					     score_board[s].score,
! 					     -score_board[s].balls_left,
! 					     score_board[s].login ) );
! 		} else if ( score_board[s].balls_left < -9 ) {
! 			center_text( s + 2, sprintf( buf, "%7d  (%2d) + %8s ",
! 					     score_board[s].score,
! 					     -score_board[s].balls_left,
! 					     score_board[s].login ) );
! 		} else if ( score_board[s].balls_left < 0 ) {
! 			center_text( s + 2, sprintf( buf, "%7d   (%1d) + %8s ",
! 					     score_board[s].score,
! 					     -score_board[s].balls_left,
! 					     score_board[s].login ) );
! 		} else {	/* no balls left */
! 			center_text( s + 2, sprintf( buf, "%7d         %8s ",
! 					     score_board[s].score,
! 					     score_board[s].login ) );
  		}
  		if ((s==scorenum) && made_it)
  		    XDrawImageString(display,win,gc,
  			(STAGE_WIDTH_IN_PIXELS - strlen(buf)*font_width)/2 
--- 115,136 ----
  	/* show score board */
  	center_text( 0, "Top Scores" );
  	for ( s = 0; s < NB_SCORES; s++ ) {
! 		if (score_board[s].balls_left==0)
! 			sprintf( buf, "%7d         %8s ",
! 				score_board[s].score, score_board[s].login);
! 		else {
! 			if (abs(score_board[s].balls_left)>99) width=3;
! 			else if (abs(score_board[s].balls_left)>9) width=2;
! 			else if (abs(score_board[s].balls_left)>0) width=1;
! 
! 		
! 			sprintf( buf, "%7d %*.s(%*d) %c %8s ",
! 				score_board[s].score, (3-width),"    ",
! 				width, abs(score_board[s].balls_left),
! 				score_board[s].balls_left>0 ? ' ' : '+',
! 				score_board[s].login);
  		}
+ 		center_text(s+2, buf);
  		if ((s==scorenum) && made_it)
  		    XDrawImageString(display,win,gc,
  			(STAGE_WIDTH_IN_PIXELS - strlen(buf)*font_width)/2 
***************
*** 162,185 ****
  
  	/* make sure the current score is on the board */
  	if ( !made_it ) {
! 		if ( balls_left > 99 ) {
! 			center_text( NB_SCORES + 3, sprintf( buf, "%7d (%3d)   %8s ",
! 					       score, balls_left, login ) );
! 		} else if ( balls_left > 9 ) {
! 			center_text( NB_SCORES + 3, sprintf( buf, "%7d  (%2d)   %8s ",
! 					       score, balls_left, login ) );
! 		} else if ( balls_left ) {
! 			center_text( NB_SCORES + 3, sprintf( buf, "%7d   (%1d)   %8s ",
! 					       score, balls_left, login ) );
! 		} else {	/* no balls left */
! 			center_text( NB_SCORES + 3, sprintf( buf, "%7d    <>   %8s ",
! 						     score, login ) );
  		}
  	}
  	/* show the current pallet shrinkage */
! 	center_text( NB_SCORES + 5, sprintf( buf, "pallet >>> %2d %% <<<",
! 			    ( pallet_modif * 100 ) / PALLET_DENOMINATOR ) );
! 
  
  	XFlush(display);
  
--- 143,165 ----
  
  	/* make sure the current score is on the board */
  	if ( !made_it ) {
! 		if (balls_left==0) 
! 			sprintf( buf, "%7d    <>   %8s ", score, login );
! 		else {
! 			if (balls_left >99) width=3;
! 			else if (balls_left >9) width=2;
! 			else if (balls_left >0) width=1;
! 		
! 			sprintf( buf, "%7d %*.s(%*d)   %8s ",
! 				score, (3-width),"    ",
! 				width, balls_left, login);
  		}
+ 		center_text( NB_SCORES +3, buf);
  	}
  	/* show the current pallet shrinkage */
! 	sprintf( buf, "pallet >>> %2d %% <<<",
! 		( pallet_modif * 100 ) / PALLET_DENOMINATOR );
! 	center_text( NB_SCORES + 5, buf);
  
  	XFlush(display);
  
diff -cr xblockbuster1.00/stage.c xblockbuster1.01/stage.c
*** xblockbuster1.00/stage.c	Fri Oct 23 00:23:18 1992
--- xblockbuster1.01/stage.c	Sat Mar 20 03:27:18 1993
***************
*** 22,29 ****
  	last_busted_brick = NULL;
  
  	/* open next stage file */
! 	if ( !( fd = fopen( sprintf( stg, STAGEFILE, playground, stage_nb ),
! 			    "r" ) ) ) {
  		perror( "Can't open stage" );
  		exit( 1 );
  	}
--- 22,29 ----
  	last_busted_brick = NULL;
  
  	/* open next stage file */
! 	sprintf( stg, STAGEFILE, playground, stage_nb );
! 	if ( !( fd = fopen(stg, "r"))) {
  		perror( "Can't open stage" );
  		exit( 1 );
  	}
***************
*** 110,116 ****
  	/* reset pallet location */
  	pallet_y = ( double ) ( pallet_yI = PALLET_MAX_Y + 4 );
  	pallet_row = MAX_ROW - 1;
! 	draw_pallet(  );
  
  	/* ready ? */
  	XDrawImageString(display, win, gc, OFFSET_BALLS, font_height*2,
--- 110,116 ----
  	/* reset pallet location */
  	pallet_y = ( double ) ( pallet_yI = PALLET_MAX_Y + 4 );
  	pallet_row = MAX_ROW - 1;
! 	if (extra_draw) draw_pallet(gc_xor );
  
  	/* ready ? */
  	XDrawImageString(display, win, gc, OFFSET_BALLS, font_height*2,
***************
*** 134,143 ****
  	/* determine stage number */
  	if ( !nb_stages ) {
  		/* read number of available stages */
! 		if ( !( fd = fopen( sprintf( buf, NB_STAGESFILE, playground ),
! 				    "r" ) ) ) {
! 			perror( sprintf( buf2, "Can't open number of stages file <%s>",
! 					 buf ) );
  			exit( 1 );
  		}
  		fscanf( fd, "%d", &nb_stages );
--- 134,145 ----
  	/* determine stage number */
  	if ( !nb_stages ) {
  		/* read number of available stages */
! 		sprintf( buf, NB_STAGESFILE, playground );
! 		if ( !( fd = fopen( buf, "r"))) {
! 
! 			sprintf( buf2, "Can't open number of stages file <%s>",
! 					 buf );
! 			perror(buf2);
  			exit( 1 );
  		}
  		fscanf( fd, "%d", &nb_stages );
***************
*** 147,153 ****
  			stages[stage_nb_tmp++] = FALSE;
  	}
  	/* search for stage index'th available stage number */
! 	stage_index = ( int ) ( random(  ) ) % nb_stages--;
  	if ( stage_index < 0 )
  		stage_index = -stage_index;
  	for ( stage_nb = 0; stages[stage_nb]; )
--- 149,155 ----
  			stages[stage_nb_tmp++] = FALSE;
  	}
  	/* search for stage index'th available stage number */
! 	stage_index = ( int ) ( RAND(  ) ) % nb_stages--;
  	if ( stage_index < 0 )
  		stage_index = -stage_index;
  	for ( stage_nb = 0; stages[stage_nb]; )
diff -cr xblockbuster1.00/xblockbuster.c xblockbuster1.01/xblockbuster.c
*** xblockbuster1.00/xblockbuster.c	Fri Mar 12 23:48:19 1993
--- xblockbuster1.01/xblockbuster.c	Mon Mar 22 01:02:53 1993
***************
*** 41,47 ****
  	struct 	timezone tzp;
  
      gettimeofday(&oldtp,&tzp);
!     draw_pallet();
      while(1) {
  	/* timer function to keep things moving at a constant speed.
  	We read time before servicing events so that the amount of time
--- 41,47 ----
  	struct 	timezone tzp;
  
      gettimeofday(&oldtp,&tzp);
!     draw_pallet(gc_xor);
      while(1) {
  	/* timer function to keep things moving at a constant speed.
  	We read time before servicing events so that the amount of time
***************
*** 89,102 ****
  			    break;
  
  			case Button2:
! 				draw_pallet(); /* erase old */
  				pallet_y = (double) (pallet_yI = PALLET_MAX_Y+4);
  				pallet_row = MAX_ROW - 1;
! 				draw_pallet(); /* draw new */
  				break;
  
  			case Button1:
! 				draw_pallet(); /* erase old */
  				if (pallet_yI > PALLET_MIN_Y) {
  					old_pallet_y = pallet_y;
  					pallet_y = (double) (pallet_yI -=16);
--- 89,102 ----
  			    break;
  
  			case Button2:
! 				draw_pallet(gc_xor); /* erase old */
  				pallet_y = (double) (pallet_yI = PALLET_MAX_Y+4);
  				pallet_row = MAX_ROW - 1;
! 				draw_pallet(gc_xor); /* draw new */
  				break;
  
  			case Button1:
! 				draw_pallet(gc_xor); /* erase old */
  				if (pallet_yI > PALLET_MIN_Y) {
  					old_pallet_y = pallet_y;
  					pallet_y = (double) (pallet_yI -=16);
***************
*** 107,113 ****
  					upwards */
  					check_deflections(old_pallet_y);
  				}
! 				draw_pallet(); /* draw new */
  				break;
  		    }
  		break;
--- 107,113 ----
  					upwards */
  					check_deflections(old_pallet_y);
  				}
! 				draw_pallet(gc_xor); /* draw new */
  				break;
  		    }
  		break;
***************
*** 132,141 ****
  		break;
  
  		case MotionNotify:
! 			draw_pallet();	/* erase old pallet */
  			pallet_x = (double) (pallet_xI =e.xmotion.x);
  			mouse_yI = e.xmotion.y;
! 			draw_pallet();	/* draw new one */
  			break;
  
  		case EnterNotify:
--- 132,141 ----
  		break;
  
  		case MotionNotify:
! 			draw_pallet(gc_xor);	/* erase old pallet */
  			pallet_x = (double) (pallet_xI =e.xmotion.x);
  			mouse_yI = e.xmotion.y;
! 			draw_pallet(gc_xor);	/* draw new one */
  			break;
  
  		case EnterNotify:
***************
*** 147,152 ****
--- 147,154 ----
  			break;
  
  		case Expose:
+ 			if (e.xexpose.count!=0) break;
+ 			XClearWindow(display,win);
  			/* redraw the stage */
  
  			for ( row = 0; row <= MAX_ROW; row++ ) {
***************
*** 155,161 ****
                          		draw_brick( row, col );
  		                draw_brick0( row, MAX_COL );
  			}
! 			draw_pallet();
  			break;
  
  		default:
--- 157,176 ----
                          		draw_brick( row, col );
  		                draw_brick0( row, MAX_COL );
  			}
! 			draw_pallet(gc_xor);
! 			print_balls();
! 			print_score();
! 			show_speeds();
! 			XDrawImageString(display, win, gc,
! 				OFFSET_SPEED, font_height*2, stage_name,
! 				strlen(stage_name));
! 			if (score_incr>1) {
! 			 	sprintf(str,"Bonus x%d",score_incr);
! 				XDrawImageString(display, win, gc,
! 				    OFFSET_SCORE, font_height*2, str, 
! 				    strlen(str));
! 			}
! 			draw_all_balls();
  			break;
  
  		default:
***************
*** 176,181 ****
--- 191,197 ----
  	struct stat	st;
  	int		len, found;
  
+ 
  	/* set default playground directory */
  	strcpy( playground, STAGEDIR );
  	strcat( playground, "/" );
***************
*** 239,244 ****
--- 255,262 ----
  	XSizeHints	size_hints;
  	XWMHints	wm_hints;
  	XClassHint	class_hints;
+ 	XTextProperty	window_name;
+ 	char *prog_name=VERSION;
  
  	/* who am i ? ['cuserid(3S)' is fooled by 'su(1)'] */
  	login = getpwuid( getuid(  ) )->pw_name;
***************
*** 254,260 ****
  		0, 0, STAGE_WIDTH_IN_PIXELS, STAGE_HEIGHT_IN_PIXELS,
  		0, 2, WhitePixel(display, screen_num));
  
- 
  	XSelectInput(display, win, ExposureMask | ButtonPressMask |
  		LeaveWindowMask | EnterWindowMask | KeyPressMask |
  		PointerMotionMask);
--- 272,277 ----
***************
*** 270,275 ****
--- 287,294 ----
  
  	xgcvalues.foreground = BlackPixel(display, screen_num);
  	xgcvalues.background = WhitePixel(display, screen_num);
+ 
+ 	
  	xgcvalues.graphics_exposures = False;
  	xgcvalues.font = font_info->fid;
  
***************
*** 287,298 ****
  	gc_erase = XCreateGC(display, win, GCForeground | GCBackground |
  		GCFont | GCGraphicsExposures | GCFunction, &xgcvalues);
  
! 	xgcvalues.function = GXxor;	/* Exclusive or */
  
! 	gc_xor = XCreateGC(display, win, GCForeground | GCBackground |
! 		GCFont | GCGraphicsExposures | GCFunction, &xgcvalues);
! 
! 
  	/* Create our icon for when the window is closed */
  
  	if  (!(icon_image = XCreateBitmapFromData(display, win,
--- 306,336 ----
  	gc_erase = XCreateGC(display, win, GCForeground | GCBackground |
  		GCFont | GCGraphicsExposures | GCFunction, &xgcvalues);
  
! 	/* Xor doesn't work very well (at all) if foreground is 0.  So
! 	 * a different function is used instead.  This seems to work,
! 	 * at least, from my fiddling with the foreground color on my
! 	 * machine. 
!  	 */
! 	xgcvalues.line_width=0;
  
! 	if (xgcvalues.foreground==0) {
! 		/* GXnor, GXinvert and GXequiv  all seem to work for the 
! 			function */
! 		xgcvalues.function = GXequiv;
! 		xgcvalues.plane_mask = xgcvalues.background;
! 		gc_xor = XCreateGC(display, win, GCForeground | GCBackground |
! 			GCFont | GCGraphicsExposures | GCFunction | 
! 			GCPlaneMask | GCLineWidth, &xgcvalues);
! 		extra_draw = TRUE;
! 	}
! 	else {
! 		xgcvalues.function = GXxor;	/* Exclusive or */
! 		gc_xor = XCreateGC(display, win, GCForeground | GCBackground |
! 			GCFont | GCGraphicsExposures | GCFunction |
! 			GCLineWidth,
! 			 &xgcvalues);
! 		extra_draw = TRUE;
! 	}
  	/* Create our icon for when the window is closed */
  
  	if  (!(icon_image = XCreateBitmapFromData(display, win,
***************
*** 317,329 ****
  	class_hints.res_name = "XBlockbuster";
  	class_hints.res_class =  "XBlockbuster";
  
! 	XmbSetWMProperties(display, win, VERSION , VERSION,
  		argv,argc, &size_hints, &wm_hints, &class_hints);
  
  
  	XMapWindow(display, win);
! 	/* initialize random (used to determine next stage_nb) */
! 	srandom( time( 0 ) );
  
  	get_playground( argc, argv );
  
--- 355,368 ----
  	class_hints.res_name = "XBlockbuster";
  	class_hints.res_class =  "XBlockbuster";
  
! 	XStringListToTextProperty(&prog_name, 1, &window_name);
! 	XSetWMProperties(display, win, &window_name, &window_name,
  		argv,argc, &size_hints, &wm_hints, &class_hints);
  
  
  	XMapWindow(display, win);
! 	/* initialize random (used to determine next stage) */
! 	SRAND( time( 0 ) );
  
  	get_playground( argc, argv );
  
***************
*** 337,339 ****
--- 376,394 ----
  
  
  }
+ 
+ #ifdef SYSV
+ 
+ /* Most SysV's don't have a usleep.  Sone of them have select. */
+ 
+ usleep( usecs )
+ int usecs;
+     {
+     struct timeval timeout;
+ 
+     timeout.tv_sec = usecs / 1000000;
+     timeout.tv_usec = usecs % 1000000;
+     select( 0, 0, 0, 0, &timeout );
+     }
+ 
+ #endif /*SYSV*/
diff -cr xblockbuster1.00/xblockbuster.h xblockbuster1.01/xblockbuster.h
*** xblockbuster1.00/xblockbuster.h	Fri Mar 12 23:48:43 1993
--- xblockbuster1.01/xblockbuster.h	Sat Mar 20 03:27:34 1993
***************
*** 10,17 ****
  
  #include <stdio.h>
  #include <pwd.h>
- /*#include <sys/file.h>
- #include <ctype.h>*/
  #include <math.h>
  #include <X11/Xlib.h>
  #include <X11/Xutil.h>
--- 10,15 ----
***************
*** 18,24 ****
--- 16,40 ----
  #include <X11/Xos.h>
  #include <X11/Xatom.h>
  
+ /*
+  * SYSTEM DEPENDENT OPTIONS
+  */
  
+ /* STAGEDIR should, in general, be defined in the (I)Makefile */
+ #ifndef STAGEDIR
+ #define STAGEDIR	"/usr/games/lib/blockbuster"
+ #endif
+ 
+ #define FONT	"10x20"
+ 
+ #define RAND() random()
+ #define SRAND(n) srandom(n)
+ 
+ /* You may need to uncomment some of these if your system does not have
+  * them.  If you need to do so, please let me know, so I can put them
+  * in an #ifdef/#endif clause to make it easier for others.
+  */
+ 
  /*
   * #define M_PI                3.14159265358979323846
   * #define M_PI_2      1.57079632679489661923
***************
*** 28,38 ****
  #define M_SQRT2_2      0.70710678118654752440
  #define NEAR_HORIZONTAL        0.7	/* < M_PI_4 */
  
  Display		*display;
  Window		win;
! GC		gc, gc_erase, gc_xor,gc_color;
  XFontStruct	*font_info;
! int		screen_num, font_width, font_height;
  
  /*** windowing objects ***/
  
--- 44,56 ----
  #define M_SQRT2_2      0.70710678118654752440
  #define NEAR_HORIZONTAL        0.7	/* < M_PI_4 */
  
+ /* Nothing below here should need to be changed. */
+ 
  Display		*display;
  Window		win;
! GC		gc, gc_erase, gc_color,gc_xor;
  XFontStruct	*font_info;
! int		screen_num, font_width, font_height,extra_draw;
  
  /*** windowing objects ***/
  
***************
*** 129,134 ****
--- 147,155 ----
  	 */
  }               ball1, ball2, ball3;
  
+ /* Macro to draw a ball */
+ 
+ 
  int             launch_quadrant;/* enumeration { NE, NW } */
  int             launch_row, launch_col;
  double          launch_x, launch_y;
***************
*** 177,190 ****
  
  /*** score and stages files ***/
  
! #define PATH_LENGTH	64
  
  char	*login;
  char	playground[PATH_LENGTH];
  
- #ifndef STAGEDIR
- #define STAGEDIR	"/usr/games/lib/blockbuster"
- #endif
  
  #define SCOREFILE      "%s/scores"
  #define NB_SCORES      12
--- 198,208 ----
  
  /*** score and stages files ***/
  
! #define PATH_LENGTH	512
  
  char	*login;
  char	playground[PATH_LENGTH];
  
  
  #define SCOREFILE      "%s/scores"
  #define NB_SCORES      12
Common subdirectories: xblockbuster1.00/STAGES/save and xblockbuster1.01/STAGES/save
Common subdirectories: xblockbuster1.00/STAGES.try/save and xblockbuster1.01/STAGES.try/save
Common subdirectories: xblockbuster1.00/STAGES.wacko/save and xblockbuster1.01/STAGES.wacko/save
*** xblockbuster1.00/xblockbuster.man	Wed Mar 10 18:12:19 1993
--- xblockbuster1.01/xblockbuster.man	Tue Mar 23 00:32:13 1993
***************
*** 87,92 ****
--- 87,96 ----
  find yourself outside the window, halting play.
  For this reason the horizontal crosshair is shown at the window border,
  helping you to keep track of the mouse.
+ .LP
+ By design, the pointer is invisible while in the XBlockBuster window.
+ I found that a visible pointer in the window was very distracting
+ during play.
  .SH "CREATION OF PLAY GROUNDS"
  A private play ground can be created in any directory.
  The stages can be defined from the ascii map codes using any text editor

--------------(END OF FILE)-------------------------------------------------

